import threading
import urllib2
import time
import os
import select
import subprocess
class DownloadVideo(threading.Thread):
	'''
	deprecated - kept for usability
	'''
	URI = None
	name = None
	turnOff = False
	def __init__(self, URI):
		self.URI = URI
		threading.Thread.__init__ (self)
		print "Started DownloadVideo thread"

	def run(self):
		# print "Retrieving " + self.URI
		name = str(int(time.time())) + ".mc"
		self.name = name
		# urllib.urlretrieve(self.URI,"/dev/shm/%s" % (name))
		request = urllib2.Request(self.URI)
		request.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')
		self.urlretrieve(urllib2.urlopen(request))
		if self.turnOff:
			print "EXIT THREAD"
			return 1

	def sourcePath(self):
		return "/dev/shm/%s" % (self.name)
		
	def stopDownload(self):
		self.turnOff = True

	def urlretrieve(self, urlfile):
		chunk = 4096
		f = open(self.sourcePath(), "wb")
		while 1 and not self.turnOff:
			data = urlfile.read(chunk)
			if not data:
				break
			f.write(data)

def decode(encodedString):
	'''
	url decoded
	'''
	import urllib
	return urllib.unquote(encodedString)

# Do not touch - magic
class MPlayer(object):
	""" A class to access a slave mplayer process
	you may want to use command(name, args*) directly
	or call populate() to access functions (and minimal doc).

	Exemples:
		mp.command('loadfile', '/desktop/funny.mp3')
		mp.command('pause')
		mp.command('quit')

	Note:
		After a .populate() call, you can access an higher level interface:
			mp.loadfile('/desktop/funny.mp3')
			mp.pause()
			mp.quit()

		Beyond syntax, advantages are:
			- completion
			- minimal documentation
			- minimal return type parsing
	"""

	exe_name = 'mplayer' if os.sep == '/' else 'mplayer.exe'

	def __init__(self):
		self._mplayer = subprocess.Popen(
				[self.exe_name, '-slave', '-quiet', '-idle', '-novideo'],
				stdin=subprocess.PIPE, stdout=subprocess.PIPE)
		self._readlines()

	def _readlines(self):
		ret = []
		while any(select.select([self._mplayer.stdout.fileno()], [], [], 0.6)):
			ret.append( self._mplayer.stdout.readline() )
		return ret

	def command(self, name, *args):
		""" Very basic interface [see populate()]
		Sends command 'name' to process, with given args
		"""
		cmd = '%s%s%s\n'%(name,
				' ' if args else '',
				' '.join(repr(a) for a in args)
				)
		print "Command! " + cmd
		self._mplayer.stdin.write(cmd)
		if name == 'quit':
			return
		return self._readlines()

	@classmethod
	def populate(kls):
		""" Populates this class by introspecting mplayer executable """
		mplayer = subprocess.Popen([kls.exe_name, '-input', 'cmdlist'],
				stdin=subprocess.PIPE, stdout=subprocess.PIPE)

		def args_pprint(txt):
			lc = txt.lower()
			if lc[0] == '[':
				return '%s=None'%lc[1:-1]
			return lc

		while True:
			line = mplayer.stdout.readline()
			if not line:
				break
			if line[0].isupper():
				continue
			args = line.split()
			cmd_name = args.pop(0)
			arguments = ', '.join([args_pprint(a) for a in args])
			func_str = '''def _populated_fn(self, *args):
			"""%(doc)s"""
			if not (%(minargc)d <= len(args) <= %(argc)d):
				raise TypeError('%(name)s takes %(argc)d arguments (%%d given)'%%len(args))
			ret = self.command('%(name)s', *args)
			if not ret:
				return None
			if ret[0].startswith('ANS'):
				val = ret[0].split('=', 1)[1].rstrip()
				try:
					return eval(val)
				except:
					return val
			return ret'''%dict(
					doc = '%s(%s)'%(cmd_name, arguments),
					minargc = len([a for a in args if a[0] != '[']),
					argc = len(args),
					name = cmd_name,
					)
			exec(func_str)

			setattr(MPlayer, cmd_name, _populated_fn)


class Hooks():
	'''
	Plugin hooks, hiermee kunnen plugins zich registeren op bepaalde evenementen (of andere functies). Dit wordt verder uitgelegt in de API documentatie
	'''
	def __init__(self):
		self.hooks = {}

	def registerHook(self, hookfunction, function):
		'''
		De functie die een functie aan een event zal registeren
		hookfunction = EVENT (example: before_startSong)
		function = functie in die klasse (example: main.playSong())
		'''
		if not hookfunction in self.hooks:
			self.hooks[hookfunction] = [] # Make a new set that'll contain all the function to be called on hook
		self.hooks[hookfunction].append(function)

	def runHooks(self, hookfunction, **kwargs):
		'''
		Met deze functie kan je alle functies die zich hebben geregisteert aan de hookfunction laten uitvoeren. Je kan hierbij ook argumenten meegeven.
		hookfunction = EVENT (example: before_startSong)
		kwargs = list van variable namen = waarde
		'''
		if hookfunction in self.hooks:
			for func in self.hooks[hookfunction]:
				if len(kwargs) > 0:
					func(kwargs)
				else:
					func()
	def unregisterHook(self, hookfunction, function):
		'''
		Indien je een functie niet meer wilt laten oproepen bij een bepaald event kan je met deze functie hem unregistere.
		hookfunction = EVENT (example: before_startSong)
		function = functie in die klasse (example: main.playSong())
		'''
		if hookfunction in self.hooks:
			if function in self.hooks[hookfunction]:
				self.hooks[hookfunction].remove(function)

	def shareVar(self, **kwargs):
		'''
		Indien het nodig is om een variable te delen met alle andere klasses kan je met sharevar een variable registeren met een waarde
		kwargs = lijst met variable namen en waardes
		'''
		for name in kwargs:
			setattr(self, name, kwargs[name])